/*
 * 文件名： RealTimeInfo.java
 * 
 * 创建日期： 2016年11月30日
 *
 * Copyright(C) 2016, by <a href="mailto:liws@xingyuanauto.com">liws</a>.
 *
 * 原始作者: liws
 *
 */
package com.moli.iov.protocol.model.realtime;

import java.io.Serializable;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.google.common.primitives.Bytes;


import com.moli.iov.protocol.codec.DataDecoder;
import com.moli.iov.protocol.codec.DataEncoder;
import com.moli.iov.protocol.codec.Serialize;
import com.moli.iov.protocol.enums.DateTimeTag;
import com.moli.iov.protocol.enums.RealTimeInfoTypeTag;
import com.moli.iov.protocol.model.Header;
import com.moli.iov.util.ByteArrayUtil;


/**
 * 实时信息上报 实体
 *
 * @author <a href="mailto:liws@xingyuanauto.com">liws</a>
 *
 * @version $Revision$
 *
 * @since 2016年11月30日
 */
@Serialize(unit = "byte", isBigEndian = true)
public class RealTimeInfoReq extends Header implements Serializable {

	/** 
	*/
	public static final long serialVersionUID = 1L;
	

	static final ThreadLocal<DateFormat> dFormat = new ThreadLocal<DateFormat>() {
		@Override
        protected DateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        }
    };
	/**
	 * 数据采集时间
	 */
	@Serialize(unit = "byte", offset = header_offset + 0, size = 6)
	public DateTimeTag collectDate;
	
	public byte[] realTimeInfoData;
	/**
	 * 解析实时上报数据
	 * @throws Exception 
	 */

	
	@Serialize(unit="byte",offset = header_offset + 6, size = -1)
	public void setRealTimeInfoData(byte[] bytes) throws Exception{
		byte[] tBytes = bytes;

		while(tBytes.length > 1){
			byte infoType = tBytes[0];
			tBytes = Arrays.copyOfRange(tBytes, 1, tBytes.length);
			switch (RealTimeInfoTypeTag.valOf(infoType)) {
			case VEHICLE_DATA:
				DataDecoder<VehicleAllReq> decoder = new DataDecoder<VehicleAllReq>();
				this.vehicleAllReq = new VehicleAllReq();
				byte[] vehicleAllBytes = Arrays.copyOfRange(tBytes, 0, vehicleAllReq.getBytesLen());
				decoder.decode(this.vehicleAllReq, vehicleAllBytes);
				tBytes = Arrays.copyOfRange(tBytes, vehicleAllReq.getBytesLen(), tBytes.length);
				break;
			case DRIVE_MOTOR_DATA:
				byte motorSize =  tBytes[0];
				this.driveMotorReq = new DriveMotorReq();
				DataDecoder<DriveMotorInfo> motorDecoder = new DataDecoder<DriveMotorInfo>();
				DriveMotorInfo driveMotorInfoReq = new DriveMotorInfo();
				this.driveMotorReq.setDriveMotorSum(motorSize);
				//去除掉驱动电机数量1字节
				tBytes = Arrays.copyOfRange(tBytes, 1, tBytes.length);
				for(int i=0;i<motorSize;i++){
					//起始值1
					byte[] motorBytes = Arrays.copyOfRange(tBytes, i*driveMotorInfoReq.getBytesLen(), (i+1)*driveMotorInfoReq.getBytesLen());
					motorDecoder.decode(driveMotorInfoReq, motorBytes);
					this.driveMotorReq.getListDriveMotors().add(driveMotorInfoReq);
				}
				//去除掉驱动点击数据字节序
				tBytes = Arrays.copyOfRange(tBytes, motorSize*driveMotorInfoReq.getBytesLen(), tBytes.length);
				break;
			case VEHICLE_LOCATION_DATA:
				DataDecoder<VehicleGpsReq> gpsDecoder = new DataDecoder<VehicleGpsReq>();
				this.vehicleGpsReq = new VehicleGpsReq();
				byte[] vehicleGpsBytes = Arrays.copyOfRange(tBytes, 0, vehicleGpsReq.getBytesLen());
				gpsDecoder.decode(this.vehicleGpsReq, vehicleGpsBytes);
				tBytes = Arrays.copyOfRange(tBytes, vehicleGpsReq.getBytesLen(), tBytes.length);
				break;
			case LIMIT_VALUE_DATA:
				DataDecoder<LimitValueReq> limDecoder = new DataDecoder<LimitValueReq>();
				this.limitValueReq = new LimitValueReq();
				byte[] vehicleLimBytes = Arrays.copyOfRange(tBytes, 0, limitValueReq.getBytesLen());
				limDecoder.decode(this.limitValueReq, vehicleLimBytes);
				tBytes = Arrays.copyOfRange(tBytes, limitValueReq.getBytesLen(), tBytes.length);
				break;
			case ALARM_DATA:
				DataDecoder<AlarmReq> alarmDecoder = new DataDecoder<AlarmReq>();
				this.alarmReq = new AlarmReq();
				alarmDecoder.decode(this.alarmReq, tBytes);
				tBytes = Arrays.copyOfRange(tBytes, alarmReq.getBytesLen(), tBytes.length);
				break;
			case CHARGE_VOLTAGE_DATA:
				byte bmsSize =  tBytes[0];
				this.bmsVoltageReq = new BmsVoltageReq();
				DataDecoder<BmsVoltageInfo> bmsDecoder = new DataDecoder<BmsVoltageInfo>();
				BmsVoltageInfo bmsVoltageInfo = null;
				this.bmsVoltageReq.setStorageSubSystemSum(bmsSize);
				tBytes = Arrays.copyOfRange(tBytes, 1, tBytes.length);

				for(int i=0;i<bmsSize;i++){
					bmsVoltageInfo = new BmsVoltageInfo();
					bmsDecoder.decode(bmsVoltageInfo, tBytes);
					//去除掉解析完成的字节序
					tBytes = Arrays.copyOfRange(tBytes, bmsVoltageInfo.getBytesLen(), tBytes.length);
					this.bmsVoltageReq.getListBmsVoltages().add(bmsVoltageInfo);
				}
				break;
			case CHARGE_TEMPERATURE_DATA:
				byte bmsTempSize =  tBytes[0];
				this.bmsTemperatureReq = new BmsTemperatureReq();
				DataDecoder<BmsTemperatureInfo> bmsTempDecoder = new DataDecoder<BmsTemperatureInfo>();
				BmsTemperatureInfo bmsTemperatureInfo = null;
				this.bmsTemperatureReq.setStorageSubSystemSum(bmsTempSize);
				tBytes = Arrays.copyOfRange(tBytes, 1, tBytes.length);
				for(int i=0;i<bmsTempSize;i++){
					bmsTemperatureInfo = new BmsTemperatureInfo();
					bmsTempDecoder.decode(bmsTemperatureInfo, tBytes);
					this.bmsTemperatureReq.getListBmsTemps().add(bmsTemperatureInfo);
					tBytes = Arrays.copyOfRange(tBytes, bmsTemperatureInfo.getBytesLen(), tBytes.length);
				}
				//tBytes = Arrays.copyOfRange(tBytes, bmsTempSize*bmsTemperatureInfo.getBytesLen(), tBytes.length);
				break;
			case EXTEND_DATA:
				while(tBytes.length > 1){
					this.extendReq = new ExtendReq();
					//截取扩展数据部分
					int extendLength = ByteArrayUtil.toInt(new byte[]{tBytes[0],tBytes[1]}) + 2;
					byte[] extendByte = Arrays.copyOfRange(tBytes, 0, extendLength);

					//解析扩展数据
					DataDecoder<ExtendReq> extendReqDecoder = new DataDecoder<ExtendReq>();
					extendReqDecoder.decode(extendReq, extendByte);
					
					//解析完成后移除扩展数据部分
					tBytes = Arrays.copyOfRange(tBytes, extendLength, tBytes.length);
					
					
				}
				//tBytes = Arrays.copyOfRange(tBytes, bmsTempSize*bmsTemperatureInfo.getBytesLen(), tBytes.length);
				break;
				
//			case REMAINING_MILEAGE_DATA:
//				DataDecoder<VehicleRemainingMileageReq> remaDecoder = new DataDecoder<VehicleRemainingMileageReq>();
//				this.vehicleRemainingMileageReq = new VehicleRemainingMileageReq();
//				byte[] vehicleRemaBytes = Arrays.copyOfRange(tBytes, 0, vehicleRemainingMileageReq.getBytesLen());
//				remaDecoder.decode(this.vehicleRemainingMileageReq, vehicleRemaBytes);
//				tBytes = Arrays.copyOfRange(tBytes, vehicleRemainingMileageReq.getBytesLen(), tBytes.length);
//				break;
//			case GPS_EXTEND_DATA:
//				DataDecoder<VehicleGpsSupplementaryReq> gpsSuppleDecoder = new DataDecoder<VehicleGpsSupplementaryReq>();
//				this.vehicleGpsSupplementaryReq = new VehicleGpsSupplementaryReq();
//				byte[] vehicleGpsSuppleBytes = Arrays.copyOfRange(tBytes, 0, vehicleGpsSupplementaryReq.getBytesLen());
//				gpsSuppleDecoder.decode(this.vehicleGpsSupplementaryReq, vehicleGpsSuppleBytes);
//				tBytes = Arrays.copyOfRange(tBytes, vehicleGpsSupplementaryReq.getBytesLen(), tBytes.length);
//				break;
			default:
				break;
			}
		}
	}
	
	
	@Serialize(unit="byte",offset = header_offset + 6, size = -1)
	public byte[] getRealTimeInfoData() {
		List<Byte> data = new ArrayList<>();
		try {
			//整车数据
			if(vehicleAllReq!=null){
				DataEncoder<VehicleAllReq> encoder = new DataEncoder<VehicleAllReq>();
				byte[] bytes = encoder.encode1(vehicleAllReq);
				data.add((byte)0x01);
				data.addAll(Bytes.asList(bytes));
			}
			//驱动电机数据
			if(driveMotorReq!=null&&driveMotorReq.getDriveMotorSum()>0){
				data.add((byte)0x02);
				data.add((byte)driveMotorReq.getDriveMotorSum());
				for(DriveMotorInfo dmi : driveMotorReq.getListDriveMotors()){
					DataEncoder<DriveMotorInfo> encoder = new DataEncoder<DriveMotorInfo>();
					byte[] bytes = encoder.encode1(dmi);
					data.addAll(Bytes.asList(bytes));
				}
			}
			//位置上报数据
			if(vehicleGpsReq!=null){
				data.add((byte)0x05);
				DataEncoder<VehicleGpsReq> encoder = new DataEncoder<VehicleGpsReq>();
				byte[] bytes = encoder.encode1(vehicleGpsReq);
				data.addAll(Bytes.asList(bytes));
			}
			//极值数据
			if(limitValueReq!=null){
				data.add((byte)0x06);
				DataEncoder<LimitValueReq> encoder = new DataEncoder<LimitValueReq>();
				byte[] bytes = encoder.encode1(limitValueReq);
				data.addAll(Bytes.asList(bytes));
			}
			//告警数据
			if(alarmReq!=null){
				data.add((byte)0x07);
				DataEncoder<AlarmReq> encoder = new DataEncoder<AlarmReq>();
				byte[] bytes = encoder.encode1(alarmReq);
				data.addAll(Bytes.asList(bytes));
			}
			//单体电池电压
			if(bmsVoltageReq!=null&&bmsVoltageReq.getListBmsVoltages().size()>0){
				data.add((byte)0x08);
				data.add((byte)bmsVoltageReq.getStorageSubSystemSum());
				DataEncoder<BmsVoltageInfo> encoder = new DataEncoder<BmsVoltageInfo>();
				byte[] bytes = encoder.encode1(bmsVoltageReq.getListBmsVoltages().get(0));
				data.addAll(Bytes.asList(bytes));
			}
			//单体电池温度
			if(bmsTemperatureReq!=null&&bmsTemperatureReq.getListBmsTemps().size()>0){
				data.add((byte)0x09);
				data.add((byte)bmsTemperatureReq.getStorageSubSystemSum());
				DataEncoder<BmsTemperatureInfo> encoder = new DataEncoder<BmsTemperatureInfo>();
				byte[] bytes = encoder.encode1(bmsTemperatureReq.getListBmsTemps().get(0));
				data.addAll(Bytes.asList(bytes));
			}
			
		}catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return Bytes.toArray(data);
	}
	
	public DateTimeTag getCollectDate() {
		return collectDate;
	}
	public void setCollectDate(DateTimeTag collectDate) {
		this.collectDate = collectDate;
	}
	public VehicleAllReq getVehicleAllReq() {
		return vehicleAllReq;
	}
	public void setVehicleAllReq(VehicleAllReq vehicleAllReq) {
		this.vehicleAllReq = vehicleAllReq;
	}
	public DriveMotorReq getDriveMotorReq() {
		return driveMotorReq;
	}
	public void setDriveMotorReq(DriveMotorReq driveMotorReq) {
		this.driveMotorReq = driveMotorReq;
	}
	public VehicleGpsReq getVehicleGpsReq() {
		return vehicleGpsReq;
	}
	public void setVehicleGpsReq(VehicleGpsReq vehicleGpsReq) {
		this.vehicleGpsReq = vehicleGpsReq;
	}
	public LimitValueReq getLimitValueReq() {
		return limitValueReq;
	}
	public void setLimitValueReq(LimitValueReq limitValueReq) {
		this.limitValueReq = limitValueReq;
	}
	public AlarmReq getAlarmReq() {
		return alarmReq;
	}
	public void setAlarmReq(AlarmReq alarmReq) {
		this.alarmReq = alarmReq;
	}
	public BmsVoltageReq getBmsVoltageReq() {
		return bmsVoltageReq;
	}
	public void setBmsVoltageReq(BmsVoltageReq bmsVoltageReq) {
		this.bmsVoltageReq = bmsVoltageReq;
	}
	public BmsTemperatureReq getBmsTemperatureReq() {
		return bmsTemperatureReq;
	}
	public void setBmsTemperatureReq(BmsTemperatureReq bmsTemperatureReq) {
		this.bmsTemperatureReq = bmsTemperatureReq;
	}


	/**
	 * 扩展数据
	 */
	public ExtendReq extendReq;
	
	public ExtendReq getExtendReq() {
		return extendReq;
	}


	public void setExtendReq(ExtendReq extendReq) {
		this.extendReq = extendReq;
	}


	/**
	 * 整车数据
	 */
	public VehicleAllReq vehicleAllReq;
	/**
	 * 驱动电机数据
	 */
	public DriveMotorReq driveMotorReq;
	/**
	 * 位置上报数据
	 */
	public VehicleGpsReq vehicleGpsReq;
	/**
	 * 极值数据
	 */
	public LimitValueReq limitValueReq;
	/**
	 * 告警数据
	 */
	public AlarmReq alarmReq;
	/**
	 * 电池单体电压数据
	 */
	public BmsVoltageReq bmsVoltageReq;
	/**
	 * 电池单体温度数据
	 */
	public BmsTemperatureReq bmsTemperatureReq;
	/**
	 * 车辆剩余里程（自定义的，先不用）
	 */
//	public VehicleRemainingMileageReq vehicleRemainingMileageReq;
	/**
	 * 车辆GPS补充数据（自定义的，先不用）
	 */
//	public VehicleGpsSupplementaryReq vehicleGpsSupplementaryReq;
	
	@Override
	public String toString() {
		StringBuilder sBuilder = new StringBuilder();
		sBuilder.append("\r\n车辆实时上报数据[VIN="+this.vin+"][CollectTime="+dFormat.get().format(collectDate.getDate())+"]\r\n");
		sBuilder.append("****************整车数据****************\r\n");
		if(this.vehicleAllReq!=null){
			sBuilder.append("车辆状态 : ["+(this.vehicleAllReq.getVehicleState()!=null?this.vehicleAllReq.getVehicleState().getK():"NULL")+"]["+(this.vehicleAllReq.getVehicleState()!=null?this.vehicleAllReq.getVehicleState().getV():"")+"]");
			sBuilder.append("\r\n");
			sBuilder.append("充电状态 : ["+(this.vehicleAllReq.getChargeState()!=null?this.vehicleAllReq.getChargeState().getK():"NULL")+"]["+(this.vehicleAllReq.getChargeState()!=null?this.vehicleAllReq.getChargeState().getV():"")+"]");
			sBuilder.append("\r\n");
			sBuilder.append("运行模式 : ["+(this.vehicleAllReq.getRunMode()!=null?this.vehicleAllReq.getRunMode().getK():"NULL")+"]["+(this.vehicleAllReq.getRunMode()!=null?this.vehicleAllReq.getRunMode().getV():"")+"]");
			sBuilder.append("\r\n");
			sBuilder.append("车速(km/h) : ["+new BigDecimal(this.vehicleAllReq.getSpeed()).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue()+"]");
            sBuilder.append("\r\n");
			sBuilder.append("累计里程(km) : ["+new BigDecimal(this.vehicleAllReq.getOdometer()).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue()+"]");
			sBuilder.append("\r\n");
			sBuilder.append("总电压(V) : ["+new BigDecimal(this.vehicleAllReq.getTotalVoltage()).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue()+"]");
			sBuilder.append("\r\n");
			sBuilder.append("总电流(A) : ["+new BigDecimal(this.vehicleAllReq.getTotalCurrent()).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue()+"]");
			sBuilder.append("\r\n");
			sBuilder.append("电池电量(1~100) % : ["+this.vehicleAllReq.getSoc()+"]");
			sBuilder.append("\r\n");
			sBuilder.append("DC-DC状态 : ["+(this.vehicleAllReq.getDcStateTag()!=null?this.vehicleAllReq.getDcStateTag().getK():"NULL")+"]["+(this.vehicleAllReq.getDcStateTag()!=null?this.vehicleAllReq.getDcStateTag().getV():"")+"]");
			sBuilder.append("\r\n");
			sBuilder.append("车辆档位 : ["+(this.vehicleAllReq.getGear()!=null?this.vehicleAllReq.getGear().getK():"NULL")+"]["+(this.vehicleAllReq.getGear()!=null?this.vehicleAllReq.getGear().getV():"")+"]");
			sBuilder.append("\r\n");
			sBuilder.append("绝缘电阻(kΩ) : ["+this.vehicleAllReq.getInsResistance()+"]");
			sBuilder.append("\r\n");
			sBuilder.append("加速踏板行程值 : ["+this.vehicleAllReq.getSpeedUpValue()+"]");
            sBuilder.append("\r\n");
            sBuilder.append("制动踏板行程值 : ["+this.vehicleAllReq.getBrakeTravelValue()+"]");
            sBuilder.append("\r\n");
		}
		//驱动电机
		sBuilder.append("****************驱动电机数据****************");
		sBuilder.append("\r\n");
		if(this.driveMotorReq!=null){
			sBuilder.append("驱动电机个数 : ["+this.driveMotorReq.getDriveMotorSum()+"]");
			sBuilder.append("\r\n");
			List<DriveMotorInfo> list = this.driveMotorReq.getListDriveMotors();
			for(DriveMotorInfo dmi : list){
				if(dmi==null)
					continue;
				sBuilder.append("电机序号 : ["+dmi.getMotorSerialNum()+"]");
				sBuilder.append("\r\n");
				sBuilder.append("驱动电机状态 : ["+(dmi.getMotorState()!=null?dmi.getMotorState().getK():"NULL")+"]["+(dmi.getMotorState()!=null?dmi.getMotorState().getV():"NULL")+"]");
				sBuilder.append("\r\n");
				sBuilder.append("驱驱动电机控制器温度 : ["+(dmi.getMotorControlTemperature())+"]");
				sBuilder.append("\r\n");
				sBuilder.append("驱动电机转速 : ["+(dmi.getMotorRotateSpeed())+"]");
				sBuilder.append("\r\n");
				sBuilder.append("驱动电机转矩 : ["+(dmi.getMotorTorque())+"]");
				sBuilder.append("\r\n");
				sBuilder.append("驱动电机温度 : ["+(dmi.getMotorTemperature())+"]");
				sBuilder.append("\r\n");
				sBuilder.append("驱动电机控制器输入电压 : ["+new BigDecimal(dmi.getMotorControlVoltage()).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue()+"]");
				sBuilder.append("\r\n");
				sBuilder.append("驱动电机控制器直流母线电流 : ["+new BigDecimal(dmi.getMotorControlCurrent()).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue()+"]");
				sBuilder.append("\r\n");
			}
		}
		//电池单体温度数据
		sBuilder.append("****************电池单体温度数据****************");
		sBuilder.append("\r\n");
		if(this.bmsTemperatureReq!=null){
			sBuilder.append("可充电储能子系统个数 : ["+this.bmsTemperatureReq.getStorageSubSystemSum()+"]");
			sBuilder.append("\r\n");
			for(BmsTemperatureInfo info : this.bmsTemperatureReq.getListBmsTemps()){
				sBuilder.append("可充电储能子系统号 : ["+info.getStorageSubSystemCode()+"]");
				sBuilder.append("\r\n");
				sBuilder.append("可充电储能子系统探针个数 : ["+info.getStorageSubSystemProbeSum()+"]");
				sBuilder.append("\r\n");
				sBuilder.append("探针温度值 : ["+info.getProbeTemperatureToString()+"]");
				sBuilder.append("\r\n");
			}
		}
		//电池单体电压数据
		sBuilder.append("****************电池单体电压数据****************");
		sBuilder.append("\r\n");
		if(this.bmsVoltageReq!=null){
			sBuilder.append("可充电储能子系统个数 : ["+this.bmsVoltageReq.getStorageSubSystemSum()+"]");
			sBuilder.append("\r\n");
			for(BmsVoltageInfo info : this.bmsVoltageReq.getListBmsVoltages()){
				sBuilder.append("可充电储能子系统号 : ["+info.getStorageSubSystemCode()+"]");
				sBuilder.append("\r\n");
				sBuilder.append("可充电储能装置电压 : ["+info.getStorageVoltage()+"]");
                sBuilder.append("\r\n");
                sBuilder.append("可充电储能装置电流 : ["+info.getStorageCurrent()+"]");
                sBuilder.append("\r\n");
                sBuilder.append("单体电池总数 : ["+info.getBatteryCellFinally()+"]");
                sBuilder.append("\r\n");
                sBuilder.append("本帧起始点序号 : ["+info.getBatteryCellStartSernum()+"]");
                sBuilder.append("\r\n");
                sBuilder.append("本帧单体电池总数 : ["+info.getBatteryCellSum()+"]");
				sBuilder.append("\r\n");
				sBuilder.append("单体电池电压 : ["+info.getBatteryCellVoltageToString()+"]");
				sBuilder.append("\r\n");
			}
		}
		//剩余里程数据
//		sBuilder.append("****************剩余里程数据****************");
//		sBuilder.append("\r\n");
//		if(this.vehicleRemainingMileageReq!=null){
//			sBuilder.append("剩余里程 : ["+this.vehicleRemainingMileageReq.getRemainingMileages()+"]");
//			sBuilder.append("\r\n");
//			
//		}
		//车辆位置数据
		sBuilder.append("****************车辆位置数据****************");
		sBuilder.append("\r\n");
		if(this.vehicleGpsReq!=null){
			sBuilder.append("车辆定位状态 : ["+(this.vehicleGpsReq.getLocationState()!=null?this.vehicleGpsReq.getLocationState().getK():"NULL")+"]["+(this.vehicleGpsReq.getLocationState()!=null?this.vehicleGpsReq.getLocationState().getV():"")+"]");
			sBuilder.append("\r\n");
			sBuilder.append("经度 : ["+new BigDecimal(this.vehicleGpsReq.getLongitude()).setScale(6, BigDecimal.ROUND_HALF_UP).doubleValue()+"]");
			sBuilder.append("\r\n");
			sBuilder.append("纬度 : ["+new BigDecimal(this.vehicleGpsReq.getLatitude()).setScale(6, BigDecimal.ROUND_HALF_UP).doubleValue()+"]");
			sBuilder.append("\r\n");
		}
		//车辆位置补充数据
//		sBuilder.append("****************车辆位置补充数据****************");
//		sBuilder.append("\r\n");
//		if(this.vehicleGpsSupplementaryReq!=null){
//			sBuilder.append("车辆速度 : ["+this.vehicleGpsSupplementaryReq.getSpeed()+"]");
//			sBuilder.append("\r\n");
//			sBuilder.append("车辆方向 : ["+this.vehicleGpsSupplementaryReq.getDirection()+"]");
//			sBuilder.append("\r\n");
//			sBuilder.append("GPS定位类型 : ["+(this.vehicleGpsSupplementaryReq.getLocationTypeTag()!=null?this.vehicleGpsSupplementaryReq.getLocationTypeTag().getK():"")+"]");
//			sBuilder.append("\r\n");
//		}
		//极值数据
		sBuilder.append("****************极值数据****************");
		sBuilder.append("\r\n");
		if(this.limitValueReq!=null){
			sBuilder.append("最高电压电池子系统号 : ["+this.limitValueReq.getHighestCellSysCode()+"]");
			sBuilder.append("\r\n");
			sBuilder.append("最高电压电池单体代号 : ["+this.limitValueReq.getHighestCellSingleCode()+"]");
			sBuilder.append("\r\n");
			sBuilder.append("电池单体电压最高值 : ["+new BigDecimal(this.limitValueReq.getCellHighestVoltage()).setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue()+"]");
			sBuilder.append("\r\n");
			sBuilder.append("最低电压电池子系统号 : ["+this.limitValueReq.getLowestCellSysCode()+"]");
			sBuilder.append("\r\n");
			sBuilder.append("最低电压电池单体代号 : ["+this.limitValueReq.getLowestCellSingleCode()+"]");
			sBuilder.append("\r\n");
			sBuilder.append("电池单体电压最低值 : ["+new BigDecimal(this.limitValueReq.getCellLowestVoltage()).setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue()+"]");
			sBuilder.append("\r\n");
			sBuilder.append("最高温度子系统号 : ["+this.limitValueReq.getHighestTemperatureSysCode()+"]");
			sBuilder.append("\r\n");
			sBuilder.append("最高温度探针序号 : ["+this.limitValueReq.getHighestTemperatureProbeNum()+"]");
			sBuilder.append("\r\n");
			sBuilder.append("最高温度值 : ["+(this.limitValueReq.getHighestTemperature())+"]");
			sBuilder.append("\r\n");
			sBuilder.append("最低温度子系统号 : ["+this.limitValueReq.getLowestTemperatureSysCode()+"]");
			sBuilder.append("\r\n");
			sBuilder.append("最低温度探针序号 : ["+this.limitValueReq.getLowestTemperatureProbeNum()+"]");
			sBuilder.append("\r\n");
			sBuilder.append("最低温度值 : ["+(this.limitValueReq.getLowestTemperature())+"]");
			sBuilder.append("\r\n");
		}
		//告警数据数据
		sBuilder.append("****************告警数据****************");
		sBuilder.append("\r\n");
		if(this.alarmReq!=null){
			sBuilder.append("故障级别 : ["+(this.alarmReq.getAlarmLevel()!=null?this.alarmReq.getAlarmLevel().getK():"NULL")+"]["+(this.alarmReq.getAlarmLevel()!=null?this.alarmReq.getAlarmLevel().getV():"")+"]");
			sBuilder.append("\r\n");
			sBuilder.append("通用报警状态 : ["+(this.alarmReq.getGeneralAlarmState()!=null?ByteArrayUtil.toHexString(this.alarmReq.getGeneralAlarmState().getV()):"")+"][\r\n"+(this.alarmReq.getGeneralAlarmState()!=null?this.alarmReq.getGeneralAlarmState().getK():"NULL")+"]");
			sBuilder.append("\r\n");
			sBuilder.append("可充电储能装置故障总数 : ["+this.alarmReq.getStoringDeviceFaultSum()+"]");
			sBuilder.append("\r\n");
			sBuilder.append("可充电储能装置故障数据 : ["+(this.alarmReq.getStoringDeviceFaultData()==null?null:ByteArrayUtil.toHexString(this.alarmReq.getStoringDeviceFaultData()))+"]");
			sBuilder.append("\r\n");
			sBuilder.append("驱动电机故障总数 : ["+this.alarmReq.getDriveMotorFaultSum()+"]");
			sBuilder.append("\r\n");
			sBuilder.append("驱动电机故障数据 : ["+(this.alarmReq.getDriveMotorFaultData()==null?null:ByteArrayUtil.toHexString(this.alarmReq.getDriveMotorFaultData()))+"]");
			sBuilder.append("\r\n");
			sBuilder.append("发动机故障总数 : ["+this.alarmReq.getEngineFaultSum()+"]");
			sBuilder.append("\r\n");
			sBuilder.append("发动机故障数据 : ["+(this.alarmReq.getEngineFaultData()==null?null:ByteArrayUtil.toHexString(this.alarmReq.getEngineFaultData()))+"]");
			sBuilder.append("\r\n");
			sBuilder.append("其他故障总数 : ["+this.alarmReq.getOtherFaultSum()+"]");
			sBuilder.append("\r\n");
			sBuilder.append("其他故障数据 : ["+(this.alarmReq.getOtherFaultData()==null?null:ByteArrayUtil.toHexString(this.alarmReq.getOtherFaultData()))+"]");
			sBuilder.append("\r\n");
		}
		
		sBuilder.append("****************扩展数据****************");
		sBuilder.append("\r\n");
		if(this.extendReq!=null){
			sBuilder.append(extendReq.toString());
		}
		return sBuilder.toString();
	}
	
	public static void main(String[] args) {
			byte[] bytes = new byte[]
				{ 0x23,0x23,0x02,(byte)0xfe,
						0x4c,0x4c,0x56,0x32,0x41,0x52,0x42,0x32,0x35,0x47,0x30,
						0x30,0x32,0x30,0x30,0x30,0x30,
						0x01,0x02,0x05,
						0x11,0x03,0x1d,0x0f,0x08,0x0b,
						0x01,0x01,0x03,0x01,0x00,0x25,0x00,0x01,0x0a,0x54,0x04,(byte)0x9d,0x27,0x35,0x20,0x01,0x25,0x12,(byte)0x95,0x00,0x00,
						0x02,0x01,0x01,0x03,0x33,0x4e,0x20,0x4e,0x2a,0x2b,0x06,0x24,0x27,0x10,
						0x05,0x00,0x06,0x58,(byte)0x99,0x06,0x01,(byte)0xc5,(byte)0xd5,0x5b,
						0x06,0x01,0x04,0x0c,0x25,0x01,0x36,0x0c,0x25,0x01,0x07,0x25,0x01,0x13,0x25,//极值数据 len=14
						0x07,0x01,0x00,0x00,0x25,0x25,0x00,0x00,0x00,0x00,0x08,0x01,0x01,0x06,0x21,
						0x27,0x10,0x00,(byte)0xe4,0x00,0x01,(byte)0xc8,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x0c,
						0x25,0x0c,0x25,0x0c,0x25,0x0c,0x25,0x09,0x01,0x01,
						0x00,0x18,0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
						0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
						0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x61};
			String string = "23 23 02 fe 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 01 01 79 12 0A 15 10 33 1C 01 01 01 01 01 2D 00 00 01 D6 0C 8C 27 10 44 01 2E 27 10 09 00 02 01 01 01 56 57 20 4E AA 48 0C 8A 27 10 05 00 06 C3 7C C4 02 09 B7 F2 06 01 08 0F 00 01 29 0E D8 01 01 3C 01 06 3B 07 00 00 00 00 00 00 00 00 00 08 01 01 0C 8C 27 10 00 54 00 01 54 0E EC 0E EC 0E EC 0E EC 0E EC 0E EC 0E EC 0F 00 0E EC 0E EC 0E EC 0E EC 0E EC 0E EC 0E EC 0E EC 0E EC 0E EC 0E EC 0E EC 0E EC 0E EC 0E EC 0E EC 0F 00 0F 00 0F 00 0E EC 0F 00 0F 00 0F 00 0F 00 0F 00 0E EC 0F 00 0F 00 0E EC 0E EC 0E EC 0E EC 0E D8 0E EC 0E D8 0E D8 0E D8 0E D8 0E EC 0E D8 0E EC 0F 00 0F 00 0E EC 0E EC 0F 00 0E EC 0F 00 0E EC 0F 00 0E EC 0E EC 0F 00 0F 00 0F 00 0F 00 0F 00 0F 00 0F 00 0F 00 0F 00 0F 00 0F 00 0F 00 0E EC 0E EC 0E EC 0E D8 0E EC 0E EC 0E EC 0E EC 0E EC 0E EC 0E EC 0E D8 09 01 01 00 0E 3C 3C 3C 3C 3C 3B 3B 3B 3C 3B 3C 3C 3C 3C A0 00 63 00 02 01 00 14 00 00 00 00 00 00 00 8C 00 01 00 00 01 18 00 1E 01 62 12 1F 02 00 47 07 05 C0 AA 50 91 96 28 94 FC 54 05 C1 24 03 02 B3 3E B2 04 37 05 C2 5E 50 27 10 44 43 04 CB 05 C3 00 00 00 00 23 01 06 2C 05 C4 05 9B 0B C7 00 00 00 2F 05 C5 00 40 01 54 0E 18 35 24 05 C6 04 48 00 22 00 00 00 00 5E";
			bytes = ByteArrayUtil.hexStringToBytes(string);

			RealTimeInfoReq realTimeInfoReq = new RealTimeInfoReq();
			DataDecoder<RealTimeInfoReq> decoder = new DataDecoder<>();
			try {
				decoder.decode(realTimeInfoReq, bytes);
			}
			catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
//			12 0A 15 10 33 1C
			System.out.println(realTimeInfoReq.toString());
			System.out.println(realTimeInfoReq.collectDate.toString());
			System.out.println(realTimeInfoReq.getVehicleGpsReq());


	}
}
